import { useEffect, useRef, RefObject } from 'react'

interface TouchGestureOptions {
  onPinch?: (scale: number) => void
  onRotate?: (angle: number) => void
  onSwipe?: (direction: 'left' | 'right' | 'up' | 'down') => void
  onDoubleTap?: () => void
  onLongPress?: () => void
  threshold?: number
  longPressDelay?: number
}

interface Touch {
  x: number
  y: number
  id: number
}

/**
 * 移动端触摸手势 Hook
 * 支持: 双指缩放、旋转、滑动、双击、长按
 */
export function useTouchGestures(
  elementRef: RefObject<HTMLElement>,
  options: TouchGestureOptions = {}
) {
  const {
    onPinch,
    onRotate,
    onSwipe,
    onDoubleTap,
    onLongPress,
    threshold = 50,
    longPressDelay = 500
  } = options

  const touchStartRef = useRef<Touch[]>([])
  const lastTapRef = useRef<number>(0)
  const longPressTimerRef = useRef<NodeJS.Timeout | null>(null)
  const initialDistanceRef = useRef<number>(0)
  const initialAngleRef = useRef<number>(0)

  useEffect(() => {
    const element = elementRef.current
    if (!element) return

    // 计算两点间距离
    const getDistance = (touch1: Touch, touch2: Touch): number => {
      const dx = touch2.x - touch1.x
      const dy = touch2.y - touch1.y
      return Math.sqrt(dx * dx + dy * dy)
    }

    // 计算两点间角度
    const getAngle = (touch1: Touch, touch2: Touch): number => {
      return Math.atan2(touch2.y - touch1.y, touch2.x - touch1.x) * 180 / Math.PI
    }

    // 触摸开始
    const handleTouchStart = (e: TouchEvent) => {
      const touches: Touch[] = Array.from(e.touches).map(t => ({
        x: t.clientX,
        y: t.clientY,
        id: t.identifier
      }))
      
      touchStartRef.current = touches

      // 检测双击
      if (onDoubleTap && touches.length === 1) {
        const now = Date.now()
        const timeSinceLastTap = now - lastTapRef.current
        
        if (timeSinceLastTap < 300 && timeSinceLastTap > 0) {
          onDoubleTap()
          lastTapRef.current = 0
        } else {
          lastTapRef.current = now
        }
      }

      // 检测长按
      if (onLongPress && touches.length === 1) {
        longPressTimerRef.current = setTimeout(() => {
          onLongPress()
        }, longPressDelay)
      }

      // 记录初始缩放距离和角度
      if (touches.length === 2) {
        initialDistanceRef.current = getDistance(touches[0], touches[1])
        initialAngleRef.current = getAngle(touches[0], touches[1])
      }
    }

    // 触摸移动
    const handleTouchMove = (e: TouchEvent) => {
      // 清除长按定时器
      if (longPressTimerRef.current) {
        clearTimeout(longPressTimerRef.current)
        longPressTimerRef.current = null
      }

      const touches: Touch[] = Array.from(e.touches).map(t => ({
        x: t.clientX,
        y: t.clientY,
        id: t.identifier
      }))

      // 双指手势：缩放和旋转
      if (touches.length === 2 && touchStartRef.current.length === 2) {
        // 缩放
        if (onPinch) {
          const currentDistance = getDistance(touches[0], touches[1])
          const scale = currentDistance / initialDistanceRef.current
          onPinch(scale)
        }

        // 旋转
        if (onRotate) {
          const currentAngle = getAngle(touches[0], touches[1])
          const angleDiff = currentAngle - initialAngleRef.current
          onRotate(angleDiff)
        }
      }
    }

    // 触摸结束
    const handleTouchEnd = (e: TouchEvent) => {
      // 清除长按定时器
      if (longPressTimerRef.current) {
        clearTimeout(longPressTimerRef.current)
        longPressTimerRef.current = null
      }

      // 检测滑动
      if (onSwipe && touchStartRef.current.length === 1 && e.changedTouches.length === 1) {
        const start = touchStartRef.current[0]
        const end = {
          x: e.changedTouches[0].clientX,
          y: e.changedTouches[0].clientY
        }

        const dx = end.x - start.x
        const dy = end.y - start.y
        const absDx = Math.abs(dx)
        const absDy = Math.abs(dy)

        if (Math.max(absDx, absDy) > threshold) {
          if (absDx > absDy) {
            onSwipe(dx > 0 ? 'right' : 'left')
          } else {
            onSwipe(dy > 0 ? 'down' : 'up')
          }
        }
      }

      touchStartRef.current = []
    }

    // 添加事件监听
    element.addEventListener('touchstart', handleTouchStart, { passive: false })
    element.addEventListener('touchmove', handleTouchMove, { passive: false })
    element.addEventListener('touchend', handleTouchEnd, { passive: false })

    return () => {
      element.removeEventListener('touchstart', handleTouchStart)
      element.removeEventListener('touchmove', handleTouchMove)
      element.removeEventListener('touchend', handleTouchEnd)
      
      if (longPressTimerRef.current) {
        clearTimeout(longPressTimerRef.current)
      }
    }
  }, [onPinch, onRotate, onSwipe, onDoubleTap, onLongPress, threshold, longPressDelay])
}

/**
 * 防止移动端双击缩放
 */
export function usePreventDoubleTapZoom(elementRef: RefObject<HTMLElement>) {
  useEffect(() => {
    const element = elementRef.current
    if (!element) return

    let lastTouchEnd = 0

    const handleTouchEnd = (e: TouchEvent) => {
      const now = Date.now()
      if (now - lastTouchEnd <= 300) {
        e.preventDefault()
      }
      lastTouchEnd = now
    }

    element.addEventListener('touchend', handleTouchEnd, { passive: false })

    return () => {
      element.removeEventListener('touchend', handleTouchEnd)
    }
  }, [elementRef])
}

/**
 * 检测设备类型和能力
 */
export function useDeviceCapabilities() {
  const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0
  const hasHover = window.matchMedia('(hover: hover)').matches
  const hasPointer = window.matchMedia('(pointer: fine)').matches
  
  return {
    isTouchDevice,
    hasHover,
    hasPointer,
    isProbablyMobile: isTouchDevice && !hasHover && !hasPointer
  }
}

